
package Sgdb::DisplayCollected ;

use Sgdb::Utils qw (:DEFAULT
                    menu_pop_common_Edit
                    menu_pop_common_View
                    bind_search_mechanism
                    bind_history_mechanism
                    tab_complete_gdb_command
                    info_line_lookup
                    ) ;



# pragmas for all
use warnings ;
use strict ;
use integer ;
use bytes ;

# Note: future multi interface option: watch globals

our $default_cmd ;

init() ;

sub init {

    $default_cmd = pref ('display-watch-default-command') || 'out/x' ;
}

sub new {

    my $self = shift or die "whoami" ;
    my $topf = shift or die "top frame needed" ;

    my $text = ( pref ('display-watch-show-scrollbars') ?
                 $topf -> Scrolled ( 'ROText', pref 'display-watch-text' ) :
                 $topf ->             ROText ( pref 'display-watch-text' ) ) ;

    pref_tags $text, 'display-watch', qw/ value expr expr-cmd no-frame frame/ ;
    { # menu
        my $m = $text -> menu() ;
        foreach my $menu ( ['cascade',
                            -label => 'Edit',
                            -menu => menu_pop_common_Edit ( $text, $m -> Menu ( -tearoff => 0, pref( 'pop-menu') ) ),
                           ],
                           ['cascade',
                            -label => 'View',
                            -menu => menu_pop_common_View ( $text, $m -> Menu ( -tearoff => 0, pref( 'pop-menu') ) ),
                           ],
                           ['separator'
                           ],
                           ['command',
                            -label => 'Close',
                            -command => [\&hook_run, 'close-current-data-pane' ]
                           ],
                         ) { $m -> add ( @$menu ) }

    }

    $text -> bind ("<Meta-Up>"   =>  sub {}) ;
    $text -> bind ("<Meta-Down>" =>  sub {}) ;
    $text -> bind ( '<Control-1>', [\&info_line_lookup, '', 1]) ;
    bind_search_mechanism $text ;

    pref_reconfigure ( 'display-watch-text' => $text,
                       ) ;

    # 1. unpacked text object
    # 2. update command
    ($text, sub { frame_update( $text, @_ ) })
}

sub get_value($) {

    my $cmd = shift ;

    my $res = gdb_exec_quiet ( $cmd ) ;
    $res ||= 'Undefined' ;
    $res =~ s/\s*\z/\n/ ;
    $res = "\n$res" if $res =~ tr/\n// > 1 ;

    $res ;
}

sub frame_update {

    return unless gdb_cached 'is-alive' ;

    my $t = shift ;

    $t -> delete ( '1.0' => 'end' ) ;

    my $i_tf = get_value 'i traced-frame' ;

    my ($tnum) = $i_tf =~ /tracepoint (\d+)/ ;

    $t -> insert ( '1.0', $i_tf => ( $tnum ? 'frame' : 'no-frame' ) ) ;

    return unless $tnum ;

    my $cmd ;
    foreach my $line ( split /^/, gdb_exec_quiet "i tracepoint $tnum" ) {

        $line =~ s/^\s*col\w*//i or next ;
        foreach ( split ',', $line ) {
            s/^\s+// ;
            s/\s+$// ;
            # check collect x if y
            if ( /if (.+)$/ ) {
                gdb_exec_quiet "out $1" or next ;
                s/if .+$// ;
            }

            if    ( /^\$reg/ ) { next }
            elsif ( /^\$arg/ ) { $cmd = 'i args' }
            elsif ( /^\$loc/ ) { $cmd = 'i local'} 
            else               { $cmd = "$default_cmd $_" }

            $t -> insert ( 'end',
                           "$_:" => 'expr',
                           get_value( $cmd ) => 'value' ) ;
        }
    }
}


